package diona.search.engine

import actors.Actor
import actors.Actor._
import diona.search.engine.Messages._
import diona.search.yasearch.YaBlogsSearch
import net.liftweb.common.Logger
import diona.model.pages.PageInfo
import diona.search.{SearchRequest, SearchItem, SearchTask}

/**
 * User: anton
 * Date: 28.07.11 20:47
 */
object SearchTaskHandler extends Actor with Logger
{
  def act()
  {
    loop {
      react {
        case Search(taskId) => handleTask(taskId)
        case AddNextTask(task, url) => {
          val nextTask = SearchTask.create(task.requestId.is, task.searchType.is, url)
          SearchTaskHandler ! Search(nextTask.id)
        }
        case GenerateNextTask(task) => generateNextTask(task)
      }
    }
  }

  def handleTask(taskId: Long)
  {
    actor {
      val task = SearchTask.byId(taskId)
      try {
        debug("Processing url " + task.requestUrl)

        val posts = YaBlogsSearch.searchByUrl(task.requestUrl.is)
        val result = SearchItem.savePosts(task, posts._2)
        SearchTask.markProcessed(taskId, result)
        posts._1 match {
          case Some(nextUrl) => SearchTaskHandler ! AddNextTask(task, nextUrl)
          case None => SearchTaskHandler ! GenerateNextTask(task)
        }
      } catch {
        case e => {
          warn("Error while processing task " + taskId, e)
          SearchTask.markFailed(taskId)
        }
      }
    }
  }

  def generateNextTask(task: SearchTask)
  {
    actor {
      PageInfo.getMinPageDateForTask(task.id) match {
        case date@Some(_) => {
          val request = SearchRequest.byId(task.requestId.is)
          val url = YaBlogsSearch.buildUrl(request.query.is, None, date)
          SearchTaskHandler ! AddNextTask(task, url)
        }
        case _ => debug("Cannot generate next task. No result for previous task.")
      }
    }
  }

}